/* eslint-disable no-underscore-dangle */
import React from 'react';
import {
  InputNumber, Row, Col, Button, message
} from 'antd';
import { isEqual } from 'lodash';
import L from 'leaflet';
import classNames from 'classnames/bind';
import { withLeaflet } from 'react-leaflet';
import { lContext } from '../index';
import styles from './index.less';
import inputImg from './img/circle.png';
import deleteImg from './img/delete.png';
import setting from './setting';

const classes = classNames.bind(styles);

class LSelect extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      originCenter: '', // 鼠标起始点坐标
      isMove: false,
      isShowInput: false,
      inputVal: 0
    };

    const eventVal = props.events.click.fields;

    const defaultVal = Object.keys(eventVal).reduce((pre, key) =>
      Object.assign(pre, { [key]: eventVal[key].value }),
    {});

    this.setDataPool(defaultVal);
  }

  componentWillMount() {
    const { leaflet: { map } } = this.props;

    // 监听地图的事件
    map.on('mousedown', this.onmouseDown);
    map.on('mousemove', this.onMove);
    map.on('mouseup', this.onmouseUp);
    map.on('contextmenu', this.onContextmenu);
  }

  componentWillReceiveProps(nextProps) {
    const { data } = this.props;
    const { data: nextData } = nextProps;
    if (nextData && nextData[0] && !isEqual(data, nextData)) {
      const { lng, lat, distance } = nextData[0];
      setTimeout(() => {
        this.setDataPool({ lng, lat, distance });
      }, 0);
      this.updateEventsDefaultValue({ lng, lat, distance });
    }
  }

  static setting = setting;

  onmouseDown = (e) => {
    const originCenter = e.latlng;
    this.setState({ originCenter });
  }

  onMove = (e) => {
    const { isMapDrag } = this.context;

    const { originCenter } = this.state;
    if (!isMapDrag && originCenter) {
      this.setState({ isMove: true, isShowInput: true });

      // 计算半径， 单位（米）
      const r = L.latLng(e.latlng).distanceTo(originCenter);
      this.drawCircleLine(originCenter, r, e);
    }
  }

  onmouseUp = (e) => {
    const { originCenter: { lng, lat }, isMove } = this.state;
    if (!isMove) return this.setState({ originCenter: '' });

    // 计算距离
    const distance = +(L.latLng(e.latlng).distanceTo({ lng, lat }) / 1000)
      .toFixed(5);

    this.setDataPool({ lng, lat, distance });
    this.setState({ isMove: false, originCenter: '' });
    const { switchMapDrag } = this.context;
    switchMapDrag(true);
  }

  onContextmenu = () => {
    const { leaflet: { map } } = this.props;
    if (map.tempCircle) {
      map.removeLayer(map.tempCircle);
    }
    if (map.polyline) {
      map.removeLayer(map.polyline);
    }
    if (map.marker) {
      map.removeLayer(map.marker);
    }
    this.setState({ isShowInput: false });
  }

  // 更新store中的dataPoll
  setDataPool(dataPoll) {
    const {
      bigScreen: { setDataPool },
      events: { click }, path, editable
    } = this.props;

    setDataPool(click, dataPoll, path, editable);
  }

  drawCircleLine = (originCenter, r, e) => {
    const {
      leaflet: { map },
      config: {
        circle: {
          bgColor, lineColor,
          lineWidth, type
        }
      }
    } = this.props;

    const dashArray = type === 'solid'
      ? []
      : type === 'dashed'
        ? [2 * lineWidth, 2 * lineWidth]
        : [0, 2 * lineWidth];
    const lineCap = type === 'dashed' ? 'butt' : 'round';

    if (map.tempCircle) {
      map.removeLayer(map.tempCircle);
    }
    if (map.polyline) {
      map.removeLayer(map.polyline);
    }
    if (map.marker) {
      map.removeLayer(map.marker);
    }

    // 绘制圆
    map.tempCircle = new L.Circle();
    map.tempCircle.setLatLng(originCenter);
    map.tempCircle.setRadius(r);
    map.tempCircle.setStyle({
      color: lineColor,
      fillColor: bgColor,
      weight: lineWidth,
      fillOpacity: 1,
      dashArray,
      lineCap
    });

    map.tempCircle.bindTooltip(
      `${(r / 1000).toFixed(3)}公里`,
      {
        permanent: true,
        className: 'distanceTool',
        direction: 'left',
        offset: L.point(-10, 0)
      }
    ).openTooltip();

    const myIcon = L.icon({
      iconUrl: deleteImg,
      iconSize: [30, 30],
      iconAnchor: [15, 40]
    });

    // 增加关闭marker
    map.marker = L.marker(
      [originCenter.lat, originCenter.lng], { icon: myIcon }
    ).addTo(map).bindTooltip('关闭圈选', {
      className: 'distanceTool',
      direction: 'right',
      offset: L.point(16, -25)
    });

    map.marker.on('click', () => this.onContextmenu());
    map.addLayer(map.tempCircle);

    if (!e) return;
    // 绘制线
    const latlngs = [
      [originCenter.lat, originCenter.lng],
      [e.latlng.lat, e.latlng.lng]
    ];
    map.polyline = L.polyline(latlngs, { color: lineColor }).addTo(map);
  }

  changeInputVal = (inputVal) => {
    // 校验不是数字，给个提示
    if (inputVal && inputVal !== '-' && inputVal !== +inputVal) {
      message.destroy();
      return message.warning('请输入数字！');
    }

    this.setState({ inputVal });
  }

  redrawCircle = () => {
    const { inputVal } = this.state;
    if (inputVal < 0) {
      message.destroy();
      return message.warning('请输入大于0的数字！');
    }

    const { leaflet: { map } } = this.props;
    this.drawCircleLine(map.tempCircle._latlng, inputVal * 1000);
    this.setDataPool({ distance: +inputVal, ...map.tempCircle._latlng });
  }

  // 更新交互事件绑定的默认值
  updateEventsDefaultValue(dataPoll) {
    const {
      bigScreen: { updateEventsDefaultValue }, path, editable
    } = this.props;

    if (!editable) return;

    const eventValues = Object.keys(dataPoll).reduce(
      (pre, key) => Object.assign(pre,
        { [`click.fields.${key}.value`]: dataPoll[key] }), {}
    );

    updateEventsDefaultValue(path, eventValues);
  }

  render() {
    const { isShowInput } = this.state;
    const { isMapDrag, switchMapDrag } = this.context;
    const {
      config: {
        btn: {
          font, backgroundColor,
          border: { type: borderStyle, ...otherBorder },
          position: { top, left }
        }
      }
    } = this.props;

    const btnStyle = {
      ...font,
      ...otherBorder,
      borderStyle,
      backgroundColor,
      top: +top,
      left: +left,
    };

    return (
      <React.Fragment>
        <div
          className={classes('areaFilter')}
          style={btnStyle}
          onClick={() => {
            switchMapDrag(!isMapDrag);
          }}
        >
          {isMapDrag ? '开启圈选' : '关闭圈选'}
        </div>
        {isShowInput && <div className={classes('areaWrap')}>
          <Row>
            <Col span={2}><img src={inputImg} alt="" width="28" /></Col>
            <Col span={4}>
              <span className={classes('inputFont')}>范围：</span>
            </Col>
            <Col span={12}>
              <InputNumber
                placeholder="请输入查询公里数"
                max={3200}
                min={0}
                step={1}
                className={classes('inputFont')}
                onPressEnter={this.redrawCircle}
                onChange={(val) => this.changeInputVal(val)}
              />
            </Col>
            <Col span={6}>
              <Button
                type="primary"
                className={classes('inputbtn')}
                onClick={this.redrawCircle}
              >
                确定
              </Button>
            </Col>
          </Row>
        </div>}
      </React.Fragment>
    );
  }
}
LSelect.contextType = lContext;

export default withLeaflet(LSelect);
